﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace az
{
    class SmallestLast
    {
        private List<Vertex> listVertex;
        private List<Vertex> listVertexCloned;
        private List<int> listVertexSorted = new List<int>();
        private bool[] colorNeighboursTab;
        private int[] colorUses;

        public void SmallestLastAlgoritm(Graph graph, Graph graphClone, bool isMaxNr, int maxNr)
        {
            listVertex = graph.listVertex;
            listVertexCloned = graphClone.listVertex;
            if (listVertex.Count > 0)
            {
                int lCloneCount = listVertexCloned.Count;
                for (int i = 0; i < lCloneCount; i++)
                {
                    int temp = listVertexCloned[0].countVertexNeighbour;
                    Vertex vertex = listVertexCloned[0];
                    foreach (Vertex v in listVertexCloned)
                        if (v.countVertexNeighbour < temp)
                        {
                            temp = v.countVertexNeighbour;
                            vertex = v;
                        }
                    int edgeCount = vertex.listEdgeConnected.Count;
                    for (int index = 0; index < edgeCount; index++)
                    {
                        Edge e = vertex.listEdgeConnected[0];
                        Vertex v1 = e.vertex1;
                        Vertex v2 = e.vertex2;
                        v1.listEdgeConnected.Remove(e);
                        v2.listEdgeConnected.Remove(e);
                        v1.listVertexNeighbor.Remove(v2);
                        v2.listVertexNeighbor.Remove(v1);
                        v1.countVertexNeighbour--;
                        v2.countVertexNeighbour--;
                        graphClone.listEdge.Remove(e);
                        graphClone.countEdge--;
                    }
                    graphClone.listVertex.Remove(vertex);
                    graphClone.countVertex--;
                    listVertexSorted.Add(vertex.number);
                }
                listVertexSorted.Reverse();
                colorNeighboursTab = new bool[graph.countVertex + 1];
                if (isMaxNr)
                {
                    colorUses = new int[graph.countVertex + 1];
                    for (int index = 0; index < colorUses.Length; index++)
                        colorUses[index] = 0;
                    foreach (int i in listVertexSorted)
                    {
                        Vertex v = null;
                        foreach (Vertex vertex in listVertex)
                            if (vertex.number == i)
                            {
                                v = vertex;
                                break;
                            }
                        for (int index = 0; index < colorNeighboursTab.Length; index++)
                            colorNeighboursTab[index] = false;
                        foreach (var vl in v.listVertexNeighbor)
                            if (vl.numberColor > 0)
                                colorNeighboursTab[vl.numberColor] = true;
                        AddColorWithMaxNr(v, 1, maxNr);
                    }
                }
                else
                {
                    foreach (int i in listVertexSorted)
                    {
                        Vertex v=null;
                        foreach (Vertex vertex in listVertex)
                            if(vertex.number==i)
                            {
                                v = vertex;
                                break;
                            }
                        for (int index = 0; index < colorNeighboursTab.Length; index++)
                            colorNeighboursTab[index] = false;
                        foreach (var vl in v.listVertexNeighbor)
                            if (vl.numberColor > 0)
                                colorNeighboursTab[vl.numberColor] = true;
                        AddColor(v, 1);
                    }
                }
                graph.isColour = true;
            }
        }

        private void AddColor(Vertex v, int l)
        {
            int k;
            k = l + 1;
            if (colorNeighboursTab[l])
                AddColor(v, k);
            else
            {
                v.numberColor = l;
                Console.WriteLine(v.number + " stopien " + v.countVertexNeighbour + " kolor " + v.numberColor);
            }
        }

        private void AddColorWithMaxNr(Vertex v, int l, int max)
        {
            int k;
            k = l + 1;
            if (colorNeighboursTab[l] || colorUses[l] == max)
                AddColorWithMaxNr(v, k, max);
            else
            {
                v.numberColor = l;
                colorUses[l]++;
                Console.WriteLine(v.number + " stopien " + v.countVertexNeighbour + " kolor " + v.numberColor);
            }
        }
    }
}
